/*
 * s_catfeed.c
 *
 *  Created on: Feb 7, 2021
 *      Author: hemingway
 */
#include <stdio.h>
#include <string.h>
#include "s_common_message.h"
#include "s_para.h"
#include "s_common_loopClock.h"
//#include "s_motor_control.h"
//#include "s_lock_buzzer.h"
//#include "s_stm32_rtc.h"
#include "s_sd3077.h"
#include <ti/sysbios/knl/Task.h>
#include "h_cc2640r2f_gpio.h"
#include "h_cc2640r2f_define.h"

#include "s_common_ble.h"

#define TEST_CMD        "TEST"

#define STATE_LED       "LED"
#define STATE_BUZZER    "BUZZER"
#define SYS_UTC         "UTC"
#define RUN_TIME        "RUNTIME"
#define HALT_TIME       "HALTTIME"
#define START_TIME      "STARTTIME"
#define END_TIME        "ENDTIME"

#define MOTOR_PWM       "PWM"
#define SYS_STATE       "STATE"

#define INT_SIZE        4


#define SPLIT_CHAR      ':'

static unsigned char stateled_cmd[] = {'L', 'E', 'D', SPLIT_CHAR, 0};
static unsigned char para_error[] = "Para-Error";

//extern UART_HandleTypeDef huart1;
//extern UART_HandleTypeDef huart4;

static unsigned int s_catfeed_sys_state = 0U;

static void s_catfeed_callback_to_run(s_common_loopClock_type type);
static void s_catfeed_callback_to_stop(s_common_loopClock_type type);

void s_catfeed_send_message(const unsigned char *data, unsigned short len)
{
//    HAL_UART_Transmit(&huart4 , data, len, 0xFFFF);
    s_common_ble_send_bleData(data, len);
}

void s_catfeed_test_callBack(const unsigned char *data, unsigned short len)
{
    // HAL_UART_Transmit(&huart4 , "data", 4, 0xFFFF);
    // HAL_UART_Transmit(&huart1 , "data", 4, 0xFFFF);
    printf("Run here and the len is %d\r\n", len);
}

void s_catfeed_change_state_led_enable(const unsigned char *data, unsigned short len)
{
    unsigned char isEnable;
    unsigned int int_value;
    unsigned char send_cmd[STRLEN(STATE_LED) + 1 + INT_SIZE] = STATE_LED;

    if(data[0] == SPLIT_CHAR) {
        memcpy(&int_value, &data[1], INT_SIZE);

        if(1 == int_value) {
            isEnable = 1;
        } else {
            isEnable = 0U;
//            HAL_GPIO_WritePin(STATE_LED_GPIO_Port, STATE_LED_Pin, GPIO_PIN_SET);
        }
        s_para_set_led_enable(isEnable);
    }


    send_cmd[STRLEN(STATE_LED)] = SPLIT_CHAR;

    int_value = s_para_get_led_enable();
    memcpy(&send_cmd[STRLEN(STATE_LED) + 1], &int_value, INT_SIZE);
    s_catfeed_send_message(send_cmd, sizeof(send_cmd));

    printf("the led state is %d\r\n", int_value);
}

void s_catfeed_change_state_buzzer_enable(const unsigned char *data, unsigned short len)
{
    unsigned char isEnable;
    unsigned int int_value;
    unsigned char send_cmd[STRLEN(STATE_BUZZER) + 1 + INT_SIZE] = STATE_BUZZER;

    if(data[0] == SPLIT_CHAR) {
        memcpy(&int_value, &data[1], INT_SIZE);
        if(1 == int_value) {
            isEnable = 1;
        } else {
            isEnable = 0U;
            // HAL_GPIO_WritePin(STATE_LED_GPIO_Port, STATE_LED_Pin, GPIO_PIN_SET);
        }
        s_para_set_buzzer_enable(isEnable);
    }


    send_cmd[STRLEN(STATE_BUZZER)] = SPLIT_CHAR;

    int_value = s_para_get_buzzer_enable();
    memcpy(&send_cmd[STRLEN(STATE_BUZZER) + 1], &int_value, INT_SIZE);
    s_catfeed_send_message(send_cmd, sizeof(send_cmd));

    printf("the buzzer state is %d\r\n", int_value);
}

void s_catfeed_change_utc(const unsigned char *data, unsigned short len)
{
    // unsigned char isEnable;
    unsigned int int_value;
    unsigned char send_cmd[STRLEN(SYS_UTC) + 1 + INT_SIZE] = SYS_UTC;

    if(data[0] == SPLIT_CHAR) {
        memcpy(&int_value, &data[1], INT_SIZE);
        S_SD3077_SetDate(int_value);
    }


    send_cmd[STRLEN(SYS_UTC)] = SPLIT_CHAR;

//    int_value = s_stm32_rtc_get_utc();
    S_SD3077_GetDate(&int_value);


    memcpy(&send_cmd[STRLEN(SYS_UTC) + 1], &int_value, INT_SIZE);
    s_catfeed_send_message(send_cmd, sizeof(send_cmd));

    printf("the utc is %d\r\n", int_value);

    if(0 == s_catfeed_sys_state) {
        s_catfeed_callback_to_run(s_common_loopClock_default_type);
    } else {
        s_catfeed_callback_to_stop(s_common_loopClock_default_type);
    }
}

void s_catfeed_change_run_time_sec(const unsigned char *data, unsigned short len)
{
    // unsigned char isEnable;
    unsigned int int_value;
    unsigned char send_cmd[STRLEN(RUN_TIME) + 1 + INT_SIZE] = RUN_TIME;

    if(SPLIT_CHAR == data[0]) {
        memcpy(&int_value, &data[1], INT_SIZE);
        s_para_set_run_time_sec(int_value);
    }


    send_cmd[STRLEN(RUN_TIME)] = SPLIT_CHAR;

    int_value = s_para_get_run_time_sec();

    memcpy(&send_cmd[STRLEN(RUN_TIME) + 1], &int_value, INT_SIZE);
    s_catfeed_send_message(send_cmd, sizeof(send_cmd));

    printf("the run time is %d\r\n", int_value);


}

void s_catfeed_change_halt_time_sec(const unsigned char *data, unsigned short len)
{
    // unsigned char isEnable;
    unsigned int int_value;
    unsigned char send_cmd[STRLEN(HALT_TIME) + 1 + INT_SIZE] = HALT_TIME;

    if(data[0] == SPLIT_CHAR) {
        memcpy(&int_value, &data[1], INT_SIZE);
        s_para_set_halt_time_sec(int_value);
    }


    send_cmd[STRLEN(HALT_TIME)] = SPLIT_CHAR;

    int_value = s_para_get_halt_time_sec();

    memcpy(&send_cmd[STRLEN(HALT_TIME) + 1], &int_value, INT_SIZE);
    s_catfeed_send_message(send_cmd, sizeof(send_cmd));

    printf("the halt time is %d\r\n", int_value);
}

void s_catfeed_change_start_day_time_sec(const unsigned char *data, unsigned short len)
{
    // unsigned char isEnable;
    unsigned int int_value;
    unsigned char send_cmd[STRLEN(START_TIME) + 1 + INT_SIZE] = START_TIME;

    if(data[0] == SPLIT_CHAR) {
        memcpy(&int_value, &data[1], INT_SIZE);
        s_para_set_day_start_time_sec(int_value);
    }
    // memcpy(&int_value, &data[1], INT_SIZE);

    // s_para_set_day_start_time_sec(int_value);

    send_cmd[STRLEN(START_TIME)] = SPLIT_CHAR;

    int_value = s_para_get_day_start_time_sec();

    memcpy(&send_cmd[STRLEN(START_TIME) + 1], &int_value, INT_SIZE);
    s_catfeed_send_message(send_cmd, sizeof(send_cmd));

    printf("the start day time is %d\r\n", int_value);

    if(0 == s_catfeed_sys_state) {
        s_catfeed_callback_to_run(s_common_loopClock_default_type);
    } else {
        s_catfeed_callback_to_stop(s_common_loopClock_default_type);
    }
}

void s_catfeed_change_end_day_time_sec(const unsigned char *data, unsigned short len)
{
    // unsigned char isEnable;
    unsigned int int_value;
    unsigned char send_cmd[STRLEN(END_TIME) + 1 + INT_SIZE] = END_TIME;

    if(data[0] == SPLIT_CHAR) {
        memcpy(&int_value, &data[1], INT_SIZE);
        s_para_set_day_end_time_sec(int_value);
    }
    // memcpy(&int_value, &data[1], INT_SIZE);
    // s_para_set_day_end_time_sec(int_value);

    send_cmd[STRLEN(END_TIME)] = SPLIT_CHAR;

    int_value = s_para_get_day_end_time_sec();

    memcpy(&send_cmd[STRLEN(END_TIME) + 1], &int_value, INT_SIZE);
    s_catfeed_send_message(send_cmd, sizeof(send_cmd));

    printf("the end day time is %d\r\n", int_value);

    if(0 == s_catfeed_sys_state) {
        s_catfeed_callback_to_run(s_common_loopClock_default_type);
    } else {
        s_catfeed_callback_to_stop(s_common_loopClock_default_type);
    }
}

void s_catfeed_pwm_callBack(const unsigned char *data, unsigned short len)
{
    unsigned int int_value;
    unsigned char send_cmd[STRLEN(MOTOR_PWM) + 1 + INT_SIZE] = MOTOR_PWM;

    if(data[0] == SPLIT_CHAR) {
        memcpy(&int_value, &data[1], INT_SIZE);
        s_para_set_motor_pwm(int_value);

        // unsigned char back_power_value = s_motor_control_getPower();
//        s_motor_control_setPower((unsigned char)int_value);

        // if(back_power_value == 0) {

        // }
//        s_motor_control_start();
        if(0U == s_catfeed_sys_state) {

            Task_sleep(100000);
//            s_motor_control_stop();
        }
    }

    send_cmd[STRLEN(MOTOR_PWM)] = SPLIT_CHAR;

    int_value = s_para_get_motor_pwm();

    memcpy(&send_cmd[STRLEN(MOTOR_PWM) + 1], &int_value, INT_SIZE);
    s_catfeed_send_message(send_cmd, sizeof(send_cmd));

    printf("the pwm is %d\r\n", int_value);



}

void s_catfeed_State_callback(const unsigned char *data, unsigned short len)
{
    unsigned char send_cmd[STRLEN(SYS_STATE) + 1 + INT_SIZE] = SYS_STATE;

    send_cmd[STRLEN(SYS_STATE)] = SPLIT_CHAR;

    memcpy(&send_cmd[STRLEN(SYS_STATE) + 1], &s_catfeed_sys_state, INT_SIZE);
    s_catfeed_send_message(send_cmd, sizeof(send_cmd));

    printf("the state is %d\r\n", s_catfeed_sys_state);
}

static void s_catfeed_callback_to_run(s_common_loopClock_type type)
{
    unsigned int new_hms_sec;
    unsigned int hms_sec_now = S_SD3077_Get_Time_Now_Second();


    // Normal mode
    if(s_para_get_day_end_time_sec() > s_para_get_day_start_time_sec()) {
        // forbiden time zone
        if(hms_sec_now < s_para_get_day_start_time_sec()) {
            new_hms_sec = s_para_get_day_start_time_sec() - hms_sec_now;
        } else if(hms_sec_now > s_para_get_day_end_time_sec()) {
            new_hms_sec = 24 * 3600 - hms_sec_now + s_para_get_day_start_time_sec();
        } else {
            new_hms_sec = s_para_get_halt_time_sec();
        }
    } else {
        // un normal mode
        if(hms_sec_now > s_para_get_day_start_time_sec()) {
            new_hms_sec = s_para_get_halt_time_sec();
        } else {
            new_hms_sec = s_para_get_halt_time_sec();
            if(hms_sec_now > s_para_get_day_end_time_sec()) {
                if(hms_sec_now + s_para_get_halt_time_sec() > s_para_get_day_start_time_sec()) {
                    new_hms_sec = s_para_get_day_start_time_sec() - hms_sec_now;
                }
            }
        }
    }

    if(s_para_get_buzzer_enable()) {
//        S_Lock_Buzzer_DeSuccess();
    }

    // new_hms_sec = 10;
    printf("s_catfeed_callback_to_run: %d\r\n", new_hms_sec);
//    s_motor_control_stop();
    H_CC2640R2F_GPIO_OutputSet(S_MOS_ENABLE_IO, 0);

    s_catfeed_sys_state = 0U;

    s_common_loopClock_specialEvt_edit_time(2, new_hms_sec);
    s_common_loopClock_specialEvt_start(2);

}

static void s_catfeed_callback_to_stop(s_common_loopClock_type type)
{
    unsigned int new_hms_sec;
    unsigned int hms_sec_now = S_SD3077_Get_Time_Now_Second();

    // Normal mode
    if(s_para_get_day_end_time_sec() > s_para_get_day_start_time_sec()) {
        // forbiden time zone
        if(hms_sec_now < s_para_get_day_start_time_sec() || hms_sec_now > s_para_get_day_end_time_sec()) {
            printf("hms now is %d, start is %d, end is %d\r\n", hms_sec_now, s_para_get_day_start_time_sec(), s_para_get_day_end_time_sec());
            printf("normal mode but forbiden\r\n");
            if(hms_sec_now < s_para_get_day_start_time_sec()) {
                new_hms_sec = s_para_get_day_start_time_sec() - hms_sec_now;
            } else {
                new_hms_sec = 24 * 3600 - hms_sec_now + s_para_get_day_start_time_sec();
            }

            printf("check next run %d\r\n", new_hms_sec);
            s_common_loopClock_specialEvt_edit_time(2, new_hms_sec);
            s_common_loopClock_specialEvt_start(2);

            return;
        } else {
            if(hms_sec_now + s_para_get_run_time_sec() > s_para_get_day_end_time_sec()) {
                new_hms_sec = s_para_get_day_end_time_sec() - hms_sec_now;
            } else {
                new_hms_sec = s_para_get_run_time_sec();
            }
        }
    } else {
        // un normal mode
        if(hms_sec_now > s_para_get_day_start_time_sec()) {
            new_hms_sec = s_para_get_run_time_sec();
            if(hms_sec_now + s_para_get_run_time_sec() > 24 * 3600) {
                if(hms_sec_now + s_para_get_run_time_sec() - 24 * 3600 > s_para_get_day_end_time_sec()) {
                    // run too long
                    new_hms_sec = 24 * 3600 - hms_sec_now + s_para_get_day_end_time_sec();
                }
            }
        } else {
            if(hms_sec_now > s_para_get_day_end_time_sec()) {
                // Forbiden time zone
                printf("un normal mode but forbiden: now:%d-start:%d-end:%d\r\n", hms_sec_now, s_para_get_day_start_time_sec(), s_para_get_day_end_time_sec());

                // if(hms_sec_now < s_para_get_day_start_time_sec()) {
                    new_hms_sec = s_para_get_day_start_time_sec() - hms_sec_now;
                // } else {

                // }


                printf("check next run %d\r\n", new_hms_sec);
                s_common_loopClock_specialEvt_edit_time(2, new_hms_sec);
                s_common_loopClock_specialEvt_start(2);

                return;
            } else {
                if(hms_sec_now + s_para_get_run_time_sec() > s_para_get_day_end_time_sec()) {
                    new_hms_sec = s_para_get_day_end_time_sec() - hms_sec_now;
                } else {
                    new_hms_sec = s_para_get_run_time_sec();
                }
            }
        }
    }

    if(s_para_get_buzzer_enable()) {
//        S_Lock_Buzzer_Success();
    }
    printf("s_catfeed_callback_to_stop: %d\r\n", new_hms_sec);

//    s_motor_control_setPower((unsigned char)s_para_get_motor_pwm());
//    s_motor_control_start();
    H_CC2640R2F_GPIO_OutputSet(S_MOS_ENABLE_IO, 1);

    s_catfeed_sys_state = 1U;

    s_common_loopClock_specialEvt_edit_time(1, new_hms_sec);
    s_common_loopClock_specialEvt_start(1);
}

void s_catfeed_init(void)
{
    s_common_message_init();
    s_common_loopClock_init();


    s_common_message_add(TEST_CMD, STRLEN(TEST_CMD), &s_catfeed_test_callBack);
    s_common_message_add(STATE_LED, STRLEN(STATE_LED), &s_catfeed_change_state_led_enable);
    s_common_message_add(STATE_BUZZER, STRLEN(STATE_BUZZER), &s_catfeed_change_state_buzzer_enable);
    s_common_message_add(SYS_UTC, STRLEN(SYS_UTC), &s_catfeed_change_utc);

//    printf("Add test rslt %d\r\n", s_common_message_add(TEST_CMD, STRLEN(TEST_CMD), &s_catfeed_test_callBack));
//    printf("Add led rslt %d\r\n", s_common_message_add(STATE_LED, STRLEN(STATE_LED), &s_catfeed_change_state_led_enable));
//    printf("Add buzzer rslt %d\r\n", s_common_message_add(STATE_BUZZER, STRLEN(STATE_BUZZER), &s_catfeed_change_state_buzzer_enable));
//    printf("Add utc rslt %d\r\n", s_common_message_add(SYS_UTC, STRLEN(SYS_UTC), &s_catfeed_change_utc));

    s_common_message_add(RUN_TIME, STRLEN(RUN_TIME), &s_catfeed_change_run_time_sec);
    s_common_message_add(HALT_TIME, STRLEN(HALT_TIME), &s_catfeed_change_halt_time_sec);
    s_common_message_add(START_TIME, STRLEN(START_TIME), &s_catfeed_change_start_day_time_sec);
    s_common_message_add(END_TIME, STRLEN(END_TIME), &s_catfeed_change_end_day_time_sec);

//    printf("Add run rslt %d\r\n", s_common_message_add(RUN_TIME, STRLEN(RUN_TIME), &s_catfeed_change_run_time_sec));
//    printf("Add halt rslt %d\r\n", s_common_message_add(HALT_TIME, STRLEN(HALT_TIME), &s_catfeed_change_halt_time_sec));
//    printf("Add start rslt %d\r\n", s_common_message_add(START_TIME, STRLEN(START_TIME), &s_catfeed_change_start_day_time_sec));
//    printf("Add end rslt %d\r\n", s_common_message_add(END_TIME, STRLEN(END_TIME), &s_catfeed_change_end_day_time_sec));

    s_common_message_add(MOTOR_PWM, STRLEN(MOTOR_PWM), &s_catfeed_pwm_callBack);
    s_common_message_add(SYS_STATE, STRLEN(SYS_STATE), &s_catfeed_State_callback);
//    printf("Add pwm rslt %d\r\n", s_common_message_add(MOTOR_PWM, STRLEN(MOTOR_PWM), &s_catfeed_pwm_callBack));
//    printf("Add sys-state rslt %d\r\n", s_common_message_add(SYS_STATE, STRLEN(SYS_STATE), &s_catfeed_State_callback));

    s_common_loopClock_specialEvt_add(1, s_catfeed_callback_to_run, s_para_get_run_time_sec()); //600s
    s_common_loopClock_specialEvt_add(2, s_catfeed_callback_to_stop, s_para_get_halt_time_sec()); //3600s

    // first run
//    s_catfeed_callback_to_stop(s_common_loopClock_default_type);

}

void s_catfeed_first_run(void)
{
    s_common_loopClock_specialEvt_edit_time(1, s_para_get_run_time_sec());
    s_common_loopClock_specialEvt_edit_time(2, s_para_get_halt_time_sec());

    printf("run: %d\r\n", s_para_get_run_time_sec());
    s_catfeed_callback_to_stop(s_common_loopClock_default_type);
}

